﻿Module extend
    'Declare some constants that can be used throughout the program
    Public MALE As String = "M"
    Public FEMALE As String = "F"

    Public ACCESS_GUEST = 0
    Public ACCESS_CAREGIVER = 1
    Public ACCESS_SUPERVISOR = 2
    Public ACCESS_STRANDED = 3
    Public ACCESS_ADMINISTRATOR = 4

    'Listings
    Private m_cImages As New Collection
    Private id As Long = 2

    'Utility functions

    'Name: Arguments
    'Usage: Arguments( item1, item2, ..., itemN )
    'Details:
    'Returns the argument array created, for formatting a string without having to declare the
    'arry for string.format explicitly.
    Public Function Arguments(ByVal ParamArray args() As Object) As Object()
        Return args
    End Function
    'Name *ChildImage
    'Usage: AddChildImage( long:child id, bitmap:image )
    'Usage: GetChildImage( long:child id )
    'Details:
    'Add will overwrite the current entry if it exists, and add the image to the collection
    'Get will return the default image if there is not an entry, or the given image
    Function GenerateID() As Long
        id += 1
        Return id - 1
    End Function
    Public Sub AddImage(ByVal id As Long, ByRef img As Bitmap)
        If m_cImages.Contains(id.ToString) Then m_cImages.Remove(id.ToString)

        m_cImages.Add(img, id)
    End Sub
    Function GetImage(ByVal id As Long) As Bitmap
        If Not m_cImages.Contains(id.ToString) Then Return My.Resources.noimage
        Return CType(m_cImages.Item(id.ToString), Bitmap)
    End Function

    'Name CheckPermission
    'Usage: CheckPermission( number: required level )
    'Returns true or false
    Sub SaveChildren()
        'Lassie

        For Each child As ChildInfo In ChildList
            Dim writer As New IO.FileStream(child.SaveFile, IO.FileMode.Create, IO.FileAccess.Write, IO.FileShare.None)
            Dim r As New IO.MemoryStream
            Dim arr As Byte()
            Dim enc As New System.Text.ASCIIEncoding
            child.Photo.Save(r, System.Drawing.Imaging.ImageFormat.Jpeg)

            arr = r.ToArray

            ReDim Preserve arr(8192)

            writer.Write(arr, 0, 8192)

            writer.Write(enc.GetBytes(child.FirstName.PadRight(32)), 0, 32)
            writer.Write(enc.GetBytes(child.LastName.PadRight(32)), 0, 32)
            writer.Write(enc.GetBytes(child.Initial.PadRight(2)), 0, 2)
            writer.Write(enc.GetBytes(child.Gender.PadRight(2)), 0, 2)
            writer.Write(enc.GetBytes(CStr(child.Age).PadRight(2)), 0, 2)
            writer.Write(enc.GetBytes(IIf(child.Arrived, "Y", "N")), 0, 1)

            writer.Write(enc.GetBytes(child.ContactInformation.Line1.PadRight(128)), 0, 128)
            writer.Write(enc.GetBytes(child.ContactInformation.Line2.PadRight(128)), 0, 128)
            writer.Write(enc.GetBytes(child.ContactInformation.City.PadRight(48)), 0, 48)
            writer.Write(enc.GetBytes(child.ContactInformation.State.PadRight(2)), 0, 2)
            writer.Write(enc.GetBytes(child.ContactInformation.ZipCode.PadRight(9)), 0, 9)
            writer.Write(enc.GetBytes(child.ContactInformation.PhoneNumber.PadRight(10)), 0, 10)

            For Each med As String In child.Medications
                If String.IsNullOrEmpty(med) Then Continue For
                writer.Write(enc.GetBytes(med & Chr(2)), 0, Len(med & Chr(2)))
            Next

            writer.Write(enc.GetBytes(Chr(1)), 0, 1)

            For Each need As String In child.MedicalNeeds
                If String.IsNullOrEmpty(need) Then Continue For
                writer.Write(enc.GetBytes(need & Chr(2)), 0, Len(need & Chr(2)))
            Next

            writer.Write(enc.GetBytes(Chr(1)), 0, 1)

            For Each behave As String In child.BehaviorAdjustments
                If String.IsNullOrEmpty(behave) Then Continue For
                writer.Write(enc.GetBytes(behave & Chr(2)), 0, Len(behave & Chr(2)))
            Next

            writer.Write(enc.GetBytes(Chr(1)), 0, 1)

            For Each diet As String In child.DietAdjustments
                If String.IsNullOrEmpty(diet) Then Continue For
                writer.Write(enc.GetBytes(diet & Chr(2)), 0, Len(diet & Chr(2)))
            Next

            writer.Close()
        Next
    End Sub
    Sub SaveUserData()
        SaveCaregivers()
        IO.File.SetAttributes(hash_add, IO.FileAttributes.Normal)
        Dim z As New IO.StreamWriter(hash_add, False)

        For Each line As String In user_registry.Keys
            z.WriteLine(line & Chr(0) & user_registry(line))
        Next

        z.Close()
        IO.File.Encrypt(My.Application.Info.DirectoryPath & "\" & hash_add)
        IO.File.SetAttributes(hash_add, IO.FileAttributes.System + IO.FileAttributes.Compressed + IO.FileAttributes.Hidden)
    End Sub
    Sub SaveCaregivers()
        For Each dude As CareGiver In ProviList
            Dim strm As New IO.FileStream(dude.SaveFile, IO.FileMode.Create, IO.FileAccess.Write, IO.FileShare.None)
            Dim enc As New System.Text.ASCIIEncoding
            Dim r As New IO.MemoryStream
            Dim arr As Byte()

            Try
                dude.Photo.Save(r, Drawing.Imaging.ImageFormat.Jpeg)
            Catch ex As Exception

            End Try

            arr = r.ToArray

            ReDim Preserve arr(8192)

            strm.Write(arr, 0, arr.Length)
            strm.Write(enc.GetBytes(dude.UserName.PadRight(33)), 0, 33)
            strm.Write(enc.GetBytes(dude.LastName.PadRight(32)), 0, 32)
            strm.Write(enc.GetBytes(dude.FirstName.PadRight(32)), 0, 32)
            strm.Write(enc.GetBytes(dude.Initial.PadRight(2)), 0, 2)
            strm.Write(enc.GetBytes(dude.ContactInformation.Line1.PadRight(128)), 0, 128)
            strm.Write(enc.GetBytes(dude.ContactInformation.Line2.PadRight(128)), 0, 128)
            strm.Write(enc.GetBytes(dude.ContactInformation.City.PadRight(48)), 0, 48)
            strm.Write(enc.GetBytes(dude.ContactInformation.State.PadRight(2)), 0, 2)
            strm.Write(enc.GetBytes(dude.ContactInformation.ZipCode.PadRight(9)), 0, 9)
            strm.Write(enc.GetBytes(dude.ContactInformation.PhoneNumber.PadRight(10)), 0, 10)
            strm.Write(enc.GetBytes(dude.ContactInformation.MobileNumber.PadRight(10)), 0, 10)
            strm.Write(enc.GetBytes(CStr(dude.SecurityLevel).PadRight(2)), 0, 2)

            strm.Close()
            IO.File.Encrypt(dude.SaveFile)
        Next
    End Sub
    Sub ResetID()
        id = 1
        m_cImages.Clear()
    End Sub
    Sub ReloadAll()
        ResetID()
        ReloadCaregivers()
        ReloadChildren()
    End Sub
    Sub ReloadCaregivers()
        ProviList.Clear()

        For Each file As String In IO.Directory.GetFiles("id\worker\", "*._", IO.SearchOption.TopDirectoryOnly)
            Dim reader As New IO.FileStream(file, IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.None)
            Dim img(8192) As Byte
            Dim the_new_you As New CareGiver(ACCESS_CAREGIVER)

            reader.Read(img, 0, 8192)

            Dim f As New IO.MemoryStream(img)
            Dim m As Bitmap
            Dim where As New ContactInformation

            m = Bitmap.FromStream(f)

            the_new_you.ID = GenerateID()

            the_new_you.Photo = m
            the_new_you.UserName = extend.ReadString(reader, 33)
            the_new_you.LastName = extend.ReadString(reader, 32)
            the_new_you.FirstName = extend.ReadString(reader, 32)
            the_new_you.Initial = extend.ReadString(reader, 2)

            where.Line1 = extend.ReadString(reader, 128)
            where.Line2 = extend.ReadString(reader, 128)
            where.City = extend.ReadString(reader, 48)
            where.State = extend.ReadString(reader, 2)
            where.ZipCode = extend.ReadString(reader, 9)
            where.PhoneNumber = extend.ReadString(reader, 10)
            where.MobileNumber = extend.ReadString(reader, 10)

            the_new_you.ContactInformation = where
            the_new_you.SaveFile = file
            Try

            Catch ex As Exception

            End Try

            'reader.Position += 2

            Dim zed As String = extend.ReadString(reader, 2)

            Try
                the_new_you.SecurityLevel = zed 'Substring(1)
            Catch ex As Exception

            End Try


            reader.Close()
            ProviList.Add(the_new_you)
        Next

            For Each dude As CareGiver In ProviList
                If ActiveUser.UserName = dude.UserName Then
                    dude.PasswordHash = ActiveUser.PasswordHash
                    ActiveUser = dude
                    Exit For
                End If
            Next
    End Sub
    Sub ReloadChildren()
        ChildList.Clear()

        For Each file As String In IO.Directory.GetFiles("id\child\", "*._", IO.SearchOption.TopDirectoryOnly)
            Dim reader As New IO.FileStream(file, IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.None)
            Try
                Dim img(8192) As Byte
                Dim the_new_you As New ChildInfo

                reader.Read(img, 0, 8192)

                Dim f As New IO.MemoryStream(img)
                Dim m As Bitmap
                Dim where As New ContactInformation
                Dim rest As String
                Dim n As Integer = 0

                m = Bitmap.FromStream(f)

                the_new_you.ID = GenerateID()

                the_new_you.Photo = m

                'writer.Write(enc.GetBytes(child.FirstName.PadRight(32)), 0, 32)
                'writer.Write(enc.GetBytes(child.LastName.PadRight(32)), 0, 32)
                'writer.Write(enc.GetBytes(child.Initial.PadRight(2)), 0, 2)
                'writer.Write(enc.GetBytes(child.Gender.PadRight(2)), 0, 2)
                'writer.Write(enc.GetBytes(CStr(child.Age).PadRight(2)), 0, 2)
                'writer.Write(enc.GetBytes(IIf(child.Arrived, "Y", "N")), 0, 1)

                'writer.Write(enc.GetBytes(child.ContactInformation.Line1.PadRight(128)), 0, 128)
                'writer.Write(enc.GetBytes(child.ContactInformation.Line2.PadRight(128)), 0, 128)
                'writer.Write(enc.GetBytes(child.ContactInformation.City.PadRight(48)), 0, 48)
                'writer.Write(enc.GetBytes(child.ContactInformation.State.PadRight(2)), 0, 2)
                'writer.Write(enc.GetBytes(child.ContactInformation.ZipCode.PadRight(9)), 0, 9)
                'writer.Write(enc.GetBytes(child.ContactInformation.PhoneNumber.PadRight(10)), 0, 10)

                the_new_you.FirstName = extend.ReadString(reader, 32)
                the_new_you.LastName = extend.ReadString(reader, 32)
                the_new_you.Initial = extend.ReadString(reader, 2)
                the_new_you.Gender = extend.ReadString(reader, 2)
                Try
                    the_new_you.Age = CInt(extend.ReadString(reader, 2))
                Catch ex As Exception
                    the_new_you.Age = -1
                End Try

                the_new_you.Arrived = extend.ReadString(reader, 1).ToLower = "y"

                where.Line1 = extend.ReadString(reader, 128)
                where.Line2 = extend.ReadString(reader, 128)
                where.City = extend.ReadString(reader, 48)
                where.State = extend.ReadString(reader, 2)
                where.ZipCode = extend.ReadString(reader, 9)
                where.PhoneNumber = extend.ReadString(reader, 10)

                reader.Position -= 1

                rest = extend.ReadString(reader, reader.Length - reader.Position)

                For Each part As String In Split(rest, Chr(1))
                    For Each chunk As String In Split(part, Chr(2))
                        Select Case n
                            Case 0 : the_new_you.Medications = chunk
                            Case 1 : the_new_you.MedicalNeeds = chunk
                            Case 2 : the_new_you.BehaviorAdjustments = chunk
                            Case 3 : the_new_you.DietAdjustments = chunk
                        End Select
                    Next
                    n += 1
                Next

                the_new_you.ContactInformation = where
                the_new_you.SaveFile = file

                reader.Close()
                ChildList.Add(the_new_you)
            Catch ex As Exception
                reader.Close()
                reader.Dispose()
                'The program failed to save a child ( :C ), so close the stream
            End Try
        Next
    End Sub
    Function CheckPermission(ByRef level As Integer) As Boolean
        'Ask the server if we have permission ( but return true for now )
        If DEBUG_MODE Then
            Return True
        Else
            Return ActiveUser.SecurityLevel >= level
        End If
    End Function
    Function ReadString(ByRef reader As IO.FileStream, ByVal len As Integer) As String
        Static block() As Byte
        Dim res As String

        ReDim block(len)

        reader.Read(block, 0, len)
        res = ""

        For Each bit As Byte In block
            If bit <> 0 Then
                res += Chr(bit)
            End If
        Next

        Return res.Trim(" ")
    End Function
    'Name AttemptLogin
    'Useage: AttemptLogin( string: username, string, md5: password )
    'Returns true or false
    Function AttemptLogin(ByVal user As String, ByVal pass As String)
        If user_registry.ContainsKey(user) Then
            If user_registry(user) = pass Then
                'Password is correct
                Return True
            End If
        End If
        Return False
    End Function
    'TERRIBLE HORRIBLE NO GOOD VERY BAD
    Function Base64Sha1(ByVal s As String) As String
        Static uni As New System.Text.UnicodeEncoding()

        Return Convert.ToBase64String(System.Security.Cryptography.SHA1.Create.ComputeHash(uni.GetBytes(s)))
    End Function
End Module
